<?php

namespace alioss;

use OSS\Core\OssException;
use OSS\Core\OssUtil;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use OSS\OssClient;
use think\facade\Env;
use think\facade\Log;

class OssAli{

    private  $accessKeyId ;
    private  $accessKeySecret;
    private  $bucket = '';
    private  $endpoint ='';
    private  $url ='';
    /**
     * @desc 安全密匙
     * @var string
     */
    private  $securityToken ='';

    private static $_instance;
    /**
     * 构造函数
     * Oss constructor.
     */
    public function __construct() {
        $this->accessKeyId = Env::get('oss.access_id');
        $this->accessKeySecret = Env::get('oss.access_key');
        $this->endpoint = Env::get('oss.endpoint');
        $this->bucket = Env::get('oss.bucket');
        $this->url = Env::get('oss.url');
        $this->securityToken = '4E0DD4AC3F6D3D0CA8B010CE69CDB824';
    }
    /**
     * 克隆
     */
    private function __clone() {
    
    }
    /**
     * 获取一个OssClient实例
     * @param $accessKeyId
     * @param $accessKeySecret
     * @param $endpoint
     * @return OssClient|null
     */
    public static function getInstance($accessKeyId,$accessKeySecret,$endpoint) {
        if (!(self::$_instance instanceof OssClient)) {
            try {
                self::$_instance = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
            } catch (OssException $e) {
                printf(__FUNCTION__ . "creating OssClient instance: FAILED\n");
                printf($e->getMessage() . "\n");
                return null;
            }
        }
        return self::$_instance;
    }
    
    
    /***
     * @desc 将本地图片上传到远程服务器
     * @param string $objectName oss对象路径名称 eg: 'hosting/ipa/20190701/ss.ipa'
     * @param string $fullName 服务器本地文件路径 eg: './upload/ipa/20190701/ss.ipa'
     * @return bool|string
     * @throws OssException
     */
    public function uploadFile($objectName, $fullName) {
        $ossClient = OssAli::getInstance($this->accessKeyId,$this->accessKeySecret,$this->endpoint);
        $data = $ossClient->uploadFile($this->bucket, $objectName, $fullName);
        if(isset($data['info'])) {
            return $this->url . '/' . $objectName;
        }
        else {
            Log::write("上传本地图片到Oss服务器错误信息" . print_r($data));
            return false;
        }
    }
    
    /***
     * @desc 将本地图片上传到远程服务器
     * @param string $objectName oss对象路径名称 eg: 'hosting/ipa/20190701/ss.ipa'
     * @param string $fullName 服务器本地文件路径 eg: './upload/ipa/20190701/ss.ipa'
     * @return bool|string
     */
    public function uploadOss($objectName, $fullName) {
        $options = array(
            OssClient::OSS_CHECK_MD5 => true,
            OssClient::OSS_PART_SIZE => 10,
        );
        try{
            $ossClient = new OssClient($this->accessKeyId,$this->accessKeySecret,$this->endpoint);

            $res = $ossClient->multiuploadFile($this->bucket, $objectName, $fullName, $options);
            if(isset($res['info'])) {
                return $this->url . '/' . $objectName;
            }
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
    }
    
    /**
     * @desc 获取oss授权token
     */
    public function getOssToken() {
        $timeout = 3600;
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint, false, $this->securityToken);
            // 生成PutObject的签名URL。
            $signedUrl = $ossClient->signUrl($this->bucket, '', $timeout, "PUT");
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n");
    
        $content = "Hello OSS.";
        $request = new RequestCore($signedUrl);
        // 生成的URL以PUT方式访问。
        $request->set_method('PUT');
        $request->add_header('Content-Type', '');
        $request->add_header('Content-Length', strlen($content));
        $request->set_body($content);
        $request->send_request();
        $res = new ResponseCore($request->get_response_header(),
            $request->get_response_body(), $request->get_response_code());
        if ($res->isOK()) {
            print(__FUNCTION__ . ": OK" . "\n");
        } else {
            print(__FUNCTION__ . ": FAILED" . "\n");
        };
        return $res;
    }

    /***
     * @desc 将远程图片下载到本地
     * @param string $objectName oss对象路径名称 eg: 'hosting/ipa/20190701/ss.ipa'
     * @param string $localFile 服务器本地文件路径 eg: './upload/ipa/20190701/ss.ipa'
     * @return bool|string
     */
    public function downloadOss($objectName, $localFile) {
        $options = array(
            OssClient::OSS_FILE_DOWNLOAD => $localFile
        );
        try{
            $ossClient = new OssClient($this->accessKeyId,$this->accessKeySecret,$this->endpoint);

            $ossClient->getObject($this->bucket, $objectName, $options);
            return true;
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
    }
}